package com.cta.view.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cta.entity.PBX;
import com.cta.entity.PBXFactory;
import com.cta.entity.Site;
import com.cta.service.ProfileService;
import com.cta.service.SiteService;
import com.cta.view.json.AssignPBXJson;
import com.cta.view.json.BaseJson;
import com.cta.view.json.JsonObject;
import com.cta.view.json.PBXFactoryJson;
import com.cta.view.json.PBXJson;
import com.cta.view.json.SiteNodeJson;

@Controller
public class PBXController extends BasicController {

	public final static String PBX = "PBX";

	@Autowired
	private SiteService siteService;

	@Autowired
	private ProfileService profileService;

	@Autowired
	private MessageSource messageSource;

	@RequestMapping(value = "/pbx-info", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<PBXJson> pbxInfo(Locale locale, Long pbxId) {
		try {
			PBXJson uj = new PBXJson();
			if (pbxId != null) {
				PBX pbx = siteService.findPBXById(pbxId);
				if (pbx != null) {
					uj.setPbxNo(pbx.getPbxNo());
					uj.setName(pbx.getName());
					uj.setDescription(pbx.getDescription());
					uj.setFactoryId(String.valueOf(pbx.getPbxFactory().getId()));
					uj.setObId(String.valueOf(pbx.getId()));
				}
			}
			return JsonObject.newJsonObject(true, uj);
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/create-pbx", method = RequestMethod.POST)
	@ResponseBody
	public String createPBX(Locale locale, String pbxNo, String name, String description, Long factoryId, Long pbxId) {
		try {
			if (pbxId != null && pbxId != 0) {
				siteService.updatePBX(pbxNo, name, description, pbxId);
				return String.format("{'success':true, msg:'%s', name: '%s'}", "Update PBX successful", name);
			} else {
				PBX pbx = siteService.createPBX(pbxNo, name, description, factoryId);
				return String.format("{'success':true, msg:'%s', obId: %s, name: '%s', thumb: 'phone.png'}", "Create PBX successful", pbx.getId(), pbx.getName());
			}
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{'success':false, msg:'%s'}", e.getMessage());
		}
	}
	
	@RequestMapping(value = "/edit-pbx", method = RequestMethod.POST)
	@ResponseBody
	public String editPBX(Locale locale, String pbxNo, String name, String description, Long factoryId, Long obId) {
		try {
			siteService.updatePBX(pbxNo, name, description, obId);
			return String.format("{'success':true, msg:'%s'}", "Update PBX successful");
			
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{'success':false, msg:'%s'}", e.getMessage());
		}
	}

	@RequestMapping(value = "/create-pbx-factory", method = RequestMethod.POST)
	@ResponseBody
	public String createPBXFactory(Locale locale, Long factoryId, String name, String description) {
		try {
			if (factoryId != null && factoryId != 0) {
				PBXFactory pbx = profileService.editPBXFactory(factoryId, name, description);
				return String.format("{'success':true, msg:'%s', name: '%s', description: '%s'}", "Edit PBX factory successful",
						pbx.getName(), pbx.getDescription());
			} else {
				PBXFactory pbx = profileService.createPBXFactory(name, description);
				return String.format("{'success':true, msg:'%s', name: '%s', id: %s}", "Create PBX successful",
						pbx.getName(), pbx.getId());
			}
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{'success':false, msg:'%s'}", "Fail to process PBX factory");
		}
	}

	/**
	 * get pbx factory info for edit pbx factory request
	 * 
	 * @param locale
	 * @param name
	 * @param description
	 * @return
	 */
	@RequestMapping(value = "/pbx-factory-info", method = RequestMethod.GET)
	@ResponseBody
	public String pbxFactoryInfo(Locale locale, Long pbxFactoryId) {
		try {
			PBXFactory pbx = profileService.findPBXFactory(pbxFactoryId);
			return String.format("{'success':true, msg:'%s', name: '%s', id: %s, description:'%s'}",
					"Get PBX successful", pbx.getName(), pbx.getId(), pbx.getDescription());
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{'success':false, msg:'%s'}", "Fail to get PBX");
		}
	}

	@RequestMapping(value = "/list-pbx-factory", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<PBXFactoryJson> listPBXFactory(Locale locale) {
		try {
			List<PBXFactory> allFactories = profileService.findAllPBXFactories();
			List<PBXFactoryJson> jsonProviders = new ArrayList<PBXFactoryJson>(allFactories.size());
			for (PBXFactory pbx : allFactories) {
				jsonProviders.add(new PBXFactoryJson(String.valueOf(pbx.getId()), pbx.getName(), pbx.getDescription()));
			}
			return JsonObject.newJsonObject(true, jsonProviders);
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/list-pbx-view", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<PBXJson> listPBXView(Locale locale, Long pbxFactoryId) {
		try {
			List<PBX> pbxs = siteService.findPBXByFactoryId(pbxFactoryId);
			// merge to list
			List<PBXJson> pbxView = new ArrayList<PBXJson>(pbxs.size());
			for (PBX p : pbxs) {
				pbxView.add(new PBXJson(null, p.getName(), p.getDescription(), "phone.png", String.valueOf(p.getId()),
						null));
			}
			return JsonObject.newJsonObject(true, pbxView);
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/list-all-pbx", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<BaseJson> listAllPBX(Locale locale) {
		try {
			List<PBX> pbxs = siteService.findAllPBX();
			List<BaseJson> pbxView = new ArrayList<BaseJson>(pbxs.size());
			for (PBX p : pbxs) {
				pbxView.add(new BaseJson(String.valueOf(p.getId()), p.getName() + " - " + p.getPbxFactory().getName(),
						null));
			}
			return JsonObject.newJsonObject(true, pbxView);
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/list-assign-pbx", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<AssignPBXJson> listAssignPBX(Locale locale) {
		try {
			List<Site> allSites = siteService.findAllSites();
			List<SiteNodeJson> sites = new ArrayList<SiteNodeJson>(allSites.size());
			for (Site site : allSites) {
				sites.add(new SiteNodeJson(null, String.valueOf(site.getId()), site.getName(), site.getDescription()));
			}
			// just get pbx which is not assign to any site node yet.
			List<PBX> pbxs = siteService.findAllPBXNotAssign();
			List<BaseJson> pbxView = new ArrayList<BaseJson>(pbxs.size());
			for (PBX p : pbxs) {
				pbxView.add(new BaseJson(null, String.valueOf(p.getId()), p.getName() + " - "
						+ p.getPbxFactory().getName(), null));
			}
			return JsonObject.newJsonObject(true, new AssignPBXJson(sites, pbxView));
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/assign-pbx", method = RequestMethod.POST)
	@ResponseBody
	public String assignPBX(Locale locale, Long assignTo, String itemselector) {
		try {
			siteService.assignPBXToSite(assignTo, itemselector);
			return String.format("{ success: true, msg: '%s'}", "Assign all pbxs ok");
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{ success: false, msg: '%s'}", "Assign pbxs fail");
		}
	}

	@RequestMapping(value = "/un-assign-pbx", method = RequestMethod.POST)
	@ResponseBody
	public String assignPBX(Locale locale, String pbxIds) {
		try {
			siteService.unAssignPBXToSite(pbxIds);
			return String.format("{ success: true, msg: '%s'}", "Un Assign all pbxs ok");
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{ success: false, msg: '%s'}", "Un Assign pbxs fail");
		}
	}

}
